<?php if (!defined('BASEPATH'))exit('No direct script access allowed');

include_once 'ExceptionDAO.php';
include_once 'util/MapError.php';
include_once 'TOItem.php';

/**
 * DAO para operações de banco para item
 * 
 * @author Douglas Rafael
 */
class DAOItem extends CI_Model {
    var $erro_number;

    
   /**
     * Lista todos os itens cadastrados (livro, magazine, mídia...).
     * 
     * @param int    $init      Posição inicial do cursor
     * @param int    $quant     Total de registros
     * @return array TOItem     Array de objetos
     * @throws ExceptionDAO
     * @throws Exception
     */
    public function select_all_itens($init, $quant) {
        try {
            $this->db->select('item.codigo, item.isbn, item.issn, item.titulo, item.subtitulo, titulo_original, item.edicao, item.ano, item.total_paginas, 
                item.descricao, item.idioma, item.localizacao, item.imagem, item.data_cadastro, item.item_tipo_id, item.editora_id, item.usuario_admin_id, 
                e.id AS editora_id, e.nome AS editora_nome, t.nome AS tipo_nome');
            $this->db->join('item_tipo t', 't.id = item_tipo_id');
            $this->db->join('editora e', 'e.id = item.editora_id', 'LEFT');
            $this->db->order_by('item.codigo', 'DESC');
            $result = $this->db->get('item', $quant, $init);
            
            //Caso ocorra erro no select
            if (!$result) {
               echo $this->db->_error_number() ;
                throw new Exception('Ocorreu um erro de banco de dados ao tentar listar os itens.');
            } else {
                //Carregando models necessários
                $this->load->model(array('DAOCategoria', 'DAOAutor'));
                $itens = array();
                foreach ($result->result() as $value) {
                    $item = new TOItem();
                    $item->codigo = $value->codigo;
                    $item->titulo = $value->titulo;
                    $item->subtitulo = $value->subtitulo;
                    $item->descricao = $value->descricao;
                    $item->localizacao = $value->localizacao;
                    $item->imagem = $value->imagem;
                    $item->data_cadastro = $value->data_cadastro;
                    $item->idioma = $value->idioma;

                    if ($value->item_tipo_id == TOItem::TIPO_BOOK) {
                        $item->livro = new TOLivro();
                        $item->livro->isbn = $value->isbn;
                        $item->livro->titulo_original = $value->titulo_original;
                        $item->livro->edicao = $value->edicao;
                        $item->livro->ano = $value->ano;
                        $item->livro->total_paginas = $value->total_paginas;

                        // Editora do livro
                        $item->livro->editora = new TOEditora();
                        $item->livro->editora->id = $value->editora_id;
                        $item->livro->editora->nome = $value->editora_nome;

                        // Autores do Item
                        $item->livro->autores = $this->DAOAutor->get_authors_item($item->codigo);
                    } elseif ($value->item_tipo_id == TOItem::TIPO_MAGAZINE) {
                        $item->magazine = new TOMagazine();
                        $item->magazine->issn = $value->issn;
                        $item->magazine->edicao = $value->edicao;
                        $item->magazine->ano = $value->ano;
                        $item->magazine->total_paginas = $value->total_paginas;

                        // Editora da magazine
                        $item->magazine->editora = new TOEditora();
                        $item->magazine->editora->id = $value->editora_id;
                        $item->magazine->editora->nome = $value->editora_nome;
                    } elseif ($value->item_tipo_id == TOItem::TIPO_MIDIA) {
                        $item->midia = new TOMidia();
                        $item->midia->ano = $value->ano;
                    }

                    $item->tipo = new TOTipo();
                    $item->tipo->id = $value->item_tipo_id;
                    $item->tipo->nome = $value->tipo_nome;

                    // Categorias do Item
                    $item->categorias = $this->DAOCategoria->get_categories_item($item->codigo);

                    array_push($itens, $item);
                }
                return $itens;
            }
        } catch (Exception $e) {
            throw new ExceptionDAO($e->getMessage());
        }
    }
    
    /**
     * Retorna o total de itens cadastrados
     * 
     * @return int Total de registros
     */
    public function amount_all_itens() {
        return $this->db->count_all_results('item');
    }
    
    /**
     * Efetua Busca por item.
     * 
     * @param int $init         Ponto Inicial do cursor no select
     * @param int $quant        Quantidade limite que deverá retornar o select
     * @param string $term      Termo a ser buscado
     * @return array TOItem     Array contendo os itens
     * @throws ExceptionDAO
     * @throws Exception
     */
    public function search_item($init, $quant, $term = NULL) {
        try {
            $this->db->select('item.codigo, item.isbn, item.issn, item.titulo, item.subtitulo, titulo_original, item.edicao, item.ano, item.total_paginas, 
                item.descricao, item.idioma, item.localizacao, item.imagem, item.data_cadastro, item.item_tipo_id, item.editora_id, item.usuario_admin_id, 
                e.id AS editora_id, e.nome AS editora_nome, t.nome AS tipo_nome');
            $this->db->join('item_tipo t', 't.id = item_tipo_id');
            $this->db->join('autor_has_item ai', 'ai.item_codigo = item.codigo', 'LEFT');
            $this->db->join('autor a', 'ai.autor_id = a.id' , 'LEFT');
            $this->db->join('editora e', 'e.id = item.editora_id', 'LEFT');
            $this->db->join('categoria_has_item ci', 'ci.item_codigo = item.codigo', 'LEFT');
            $this->db->join('categoria c', 'ci.categoria_id = c.id' , 'LEFT');
            $this->db->where("(item.codigo LIKE '%" . $term . "%' OR item.titulo LIKE '%" . $term . "%' OR a.nome LIKE '%" . $term . "%' OR e.nome LIKE '%" . $term . "%' OR c.nome LIKE '%" . $term . "%')");
            $this->db->group_by('item.codigo');
            $this->db->order_by('item.codigo', 'DESC');
            $result = $this->db->get('item', $quant, $init);
            
            //Caso ocorra erro no select
            if (!$result) {
                throw new Exception('Ocorreu um erro de banco de dados ao tentar efetuar busca por livros.');
            } else {
                //Carregando models necessários
                $this->load->model(array('DAOCategoria', 'DAOAutor'));
                $itens = array();
                foreach ($result->result() as $value) {
                    $item = new TOItem();
                    $item->codigo = $value->codigo;
                    $item->titulo = $value->titulo;
                    $item->subtitulo = $value->subtitulo;
                    $item->descricao = $value->descricao;
                    $item->localizacao = $value->localizacao;
                    $item->imagem = $value->imagem;
                    $item->data_cadastro = $value->data_cadastro;
                    $item->idioma = $value->idioma;

                    if ($value->item_tipo_id == TOItem::TIPO_BOOK) {
                        $item->livro = new TOLivro();
                        $item->livro->isbn = $value->isbn;
                        $item->livro->titulo_original = $value->titulo_original;
                        $item->livro->edicao = $value->edicao;
                        $item->livro->ano = $value->ano;
                        $item->livro->total_paginas = $value->total_paginas;

                        // Editora do livro
                        $item->livro->editora = new TOEditora();
                        $item->livro->editora->id = $value->editora_id;
                        $item->livro->editora->nome = $value->editora_nome;

                        // Autores do Item
                        $item->livro->autores = $this->DAOAutor->get_authors_item($item->codigo);
                    } elseif ($value->item_tipo_id == TOItem::TIPO_MAGAZINE) {
                        $item->magazine = new TOMagazine();
                        $item->magazine->issn = $value->issn;
                        $item->magazine->edicao = $value->edicao;
                        $item->magazine->ano = $value->ano;
                        $item->magazine->total_paginas = $value->total_paginas;

                        // Editora da magazine
                        $item->magazine->editora = new TOEditora();
                        $item->magazine->editora->id = $value->editora_id;
                        $item->magazine->editora->nome = $value->editora_nome;
                    } elseif ($value->item_tipo_id == TOItem::TIPO_MIDIA) {
                        $item->midia = new TOMidia();
                        $item->midia->ano = $value->ano;
                    }

                    $item->tipo = new TOTipo();
                    $item->tipo->id = $value->item_tipo_id;
                    $item->tipo->nome = $value->tipo_nome;

                    // Categorias do Item
                    $item->categorias = $this->DAOCategoria->get_categories_item($item->codigo);

                    array_push($itens, $item);
                }
                return $itens;
            }
        } catch (Exception $e) {
            throw new ExceptionDAO($e->getMessage());
        }
    }
    
    
    /**
     * Retorna a quantidade de registros da busca por item
     * 
     * @param string $term Termo a ser buscado
     * @return int
     */
    public function amount_search_item($term) {
        $this->db->join('item_tipo t', 't.id = item_tipo_id');
        $this->db->join('autor_has_item ai', 'ai.item_codigo = item.codigo', 'LEFT');
        $this->db->join('autor a', 'ai.autor_id = a.id', 'LEFT');
        $this->db->join('editora e', 'e.id = item.editora_id', 'LEFT');
        $this->db->join('categoria_has_item ci', 'ci.item_codigo = item.codigo', 'LEFT');
        $this->db->join('categoria c', 'ci.categoria_id = c.id', 'LEFT');
        $this->db->where("(item.codigo LIKE '%" . $term . "%' OR item.titulo LIKE '%" . $term . "%' OR a.nome LIKE '%" . $term . "%' OR e.nome LIKE '%" . $term . "%' OR c.nome LIKE '%" . $term . "%')");
        $this->db->group_by('item.codigo', 'ASC');
        $result = $this->db->get('item');

        return count($result->result());
    }
    

    /**
     * Verifica se existe item cadastrado de acordo com o codigo passado como parametro
     * - TRUE é retornado caso possua cadastro
     * - FALSE é retornado caso não possua acadastro
     * 
     * @param  int $codigo_item
     * @return boolean
     */
    public function check_item($codigo_item) {
        $this->db->select('codigo');
        $this->db->where('codigo', $codigo_item);

        if ($this->db->count_all_results('item') > 0)
            return TRUE;
        else
            return FALSE;
    }

    /**
     * Verifica qual o tipo do item para chamar o get_item respectivo
     * 
     * @param TOItem $item
     * @return type
     */
    public function get_item(TOItem $item) {
        if ($item->tipo->id == TOItem::TIPO_BOOK) {
            $this->load->model('DAOLivro');
            $item = $this->DAOLivro->get_book($item);
        } elseif ($item->tipo->id == TOItem::TIPO_MAGAZINE) {
            $this->load->model('DAOMagazine');
            $item = $this->DAOMagazine->get_magazine($item);
        } elseif ($item->tipo->id == TOItem::TIPO_MIDIA) {
            $this->load->model('DAOMidia');
            $item = $this->DAOMidia->get_media($item);
        }
        return $item;
    }

    /**
     * Retorna sugestões de itens de acordo com o term digitado
     * Útil para utilizar no autocomplete
     * 
     * @param $term
     * @return type 
     */
    public function suggestion_itens($term) {
        $this->load->helper('text');
        
        $this->db->select('codigo, titulo, subtitulo, item_tipo_id, item_tipo.nome AS tipo_nome, imagem, GROUP_CONCAT(autor.nome) AS autor, editora.nome AS editora');
        $this->db->join('autor_has_item ai', 'ai.item_codigo = item.codigo', 'LEFT');
        $this->db->join('autor', 'autor.id = ai.autor_id', 'LEFT');
        $this->db->join('editora', 'editora.id = item.editora_id', 'LEFT');
        $this->db->join('item_tipo', 'item_tipo_id = item_tipo.id');
        $this->db->like('titulo', $term);
        $this->db->or_like('codigo', $term);
        $this->db->group_by('item.codigo');
        $result = $this->db->get('item', 30);
        
        $itens = array();
        if ($result) {
            foreach ($result->result() as $value) {
                $data['label']   = $value->titulo;
                $data['titulo']  = $value->titulo;
                $data['codigo']  = $value->codigo;
                $data['tipo']    = $value->item_tipo_id;
                $data['image']   = $value->imagem;
                $data['autor']   = character_limiter($value->autor, 25);
                $data['editora'] = $value->editora;
                if($value->item_tipo_id == TOItem::TIPO_BOOK){
                    $data['category'] = 'Livro';
                }else if($value->item_tipo_id == TOItem::TIPO_MAGAZINE){
                    $data['category'] = 'Magazine (revista, jornal...)';
                    $data['autor']    = 'Não possui';
                }elseif ($value->item_tipo_id == TOItem::TIPO_MIDIA) {
                    $data['category'] = 'Mídia (DVD, CD...)';
                    $data['autor']    = 'Não possui';
                    $data['editora']  = 'Não possui';
                }else{
                    $data['category'] = "";
                }
                
                array_push($itens, $data);
            }
            return $itens;
        }
    }
    
    /**
     * Retorna dados simples de um item de acordo com seu código
     * 
     * @param type $codigo_item
     * @return \TOItem
     * @throws ExceptionDAO
     * @throws Exception
     */
    public function get_item_simple($codigo_item) {
        try {
            $this->db->select('codigo, titulo, subtitulo');
            $this->db->where('codigo', $codigo_item);
            $result = $this->db->get('item');
            if(!$result){
                throw new Exception('Ocorreu um erro de banco de dados ao tentar selecionar item.');
            } else {
                $value = $result->row();
                
                $item = new TOItem();
                $item->codigo = $value->codigo;
                $item->titulo = $value->titulo;
                $item->subtitulo = $value->subtitulo;
                
                return $item;
            }
        } catch (Exception $e) {
            throw new ExceptionDAO($e->getMessage());
        }
    }
    
    
    /**
     * Trata o total para manipulação. Útil para verficar no update dos itens
     *  - Garante que o total para manipulação seja IGUAL ou MAIOR que o total de emprestimos ativos
     *  - Se passar na condição (novo total manipulação maior > total de emprestimos ativos) 
     * é retornado o total correto de itens disponiveis para empréstimos (para salvar no BANCO)
     *       - CALC --- (Novo Total para manipulação - Total de emprestimos ativos)
     * 
     * @param  int $codigo_item                 Código do item
     * @param  int $novo_total_manipulacao      Novo Total para manipulação do item
     * @return int Total correto para maipulação do item
     * @throws ExceptionValidacao
     * @throws Exception
     */    
    public function treat_amount_manipulation($codigo_item, $novo_total_manipulacao) {
        try {
            // Pegando os dados a serem utilizados
            $this->load->model('DAOEmprestimo');
            $emprestimo = $this->DAOEmprestimo->get_loans_item($codigo_item, NULL, NULL, TRUE);

            $total_emprestimo_ativo = 0;
            foreach ($emprestimo as $emprestimo_vez) {
                $emprestimo_vez->emprestimo_item->status == 1 ? $total_emprestimo_ativo += abs($emprestimo_vez->emprestimo_item->total - $emprestimo_vez->emprestimo_item->total_devolvido) : '';
            }
            if (($total_emprestimo_ativo > 0 && $novo_total_manipulacao < $total_emprestimo_ativo)) {
                throw new Exception('<p>A nova quantidade informada para empréstimos é inferior a quantidade de itens com empréstimos ATIVOS.</p>'.
                        '<p><span class="bold">Total de itens em circulação (com empréstimos ATIVOS): </span>' . string_fill($total_emprestimo_ativo,2,0) .
                        '</p><p><span class="bold">Novo total informado de itens para empréstimo: </span>' . string_fill($novo_total_manipulacao, 4, 0) .
                        '</p><p><span class="bold"><i>1° - Observe que o total de itens que estão emprestado excede o total que está sendo fornecido.</i></span>' .
                        '</p><p><span class="bold"><i>2° - Para atualizar o item com este valor, os exemplares em cirulação deverão ser devolvidos. Ou informe uma quantidade IGUAL ou SUPERIOR ao total de itens em circulão</span>');
            } else {
                return abs($novo_total_manipulacao - $total_emprestimo_ativo);
            }
        } catch (Exception $e) {
            throw new ExceptionValidacao($e->getMessage());
        }
    }
    

}